Using NodesUsing TIC80 NodeOn this pageUsing TIC80 Node The TIC80Node is a node class in Dora SSR that allows you to run TIC-80 cart files in your game scenes. It inherits from Sprite, which means you can use all the properties and methods available to sprite nodes, such as positioning, scaling, rotation, and more. TIC80Node provides a complete TIC-80 virtual machine environment, enabling you to integrate retro-style games and programs created with the TIC-80 fantasy console into your Dora SSR projects. This tutorial will guide you through using TIC80Node, including how to work with TIC-80 cart files, how to use the Web IDE integration for editing, and how to create and use TIC80Node instances in your game. 1. TIC-80 Cart File Format TIC-80 is a fantasy computer for making, playing, and sharing tiny games. TIC80Node allows you to run TIC-80 cart files directly in your Dora SSR projects. A TIC-80 cart file contains a complete game or program, including code, graphics, sound, and other resources. 1.1 Supported File Formats TIC80Node supports two cart file formats: .tic format: The native TIC-80 cart file format .png format: TIC-80 carts can also be embedded in PNG images for easy sharing 1.2 TIC80Node Features When running a TIC-80 cart through TIC80Node, you get: Full TIC-80 API support: Complete access to TIC-80's drawing, sound, input, and other APIs Keyboard, controller, and touch input handling: Automatic input mapping to TIC-80 controls Audio playback: Full audio support through the TIC-80 sound engine Native resolution: Runs at TIC-80's native resolution of 240x136 pixels Fixed frame rate: Runs at 60 FPS, matching TIC-80's specification 2. Using Web IDE to Edit TIC-80 Carts Dora SSR's Web IDE provides integrated support for TIC80 Studio, making it easy to edit TIC-80 cart files directly within your development environment. 2.1 Opening TIC-80 Terminal To edit a TIC-80 cart file: In the Web IDE file tree, click on a .tic file The TIC80 Studio terminal will open, allowing you to edit the cart 2.2 Uploading Cart to TIC80 Studio Once the TIC80 terminal is open, you can upload your cart file for editing: Type the add command in the TIC80 terminal This will upload the currently opened .tic cart file to the TIC80 Studio environment You can now edit the code, graphics, and audio resources using TIC80 Studio's tools 2.3 Saving Changes Back to File After editing your cart in TIC80 Studio: Type get <filename> in the TIC80 terminal, where <filename> is the name of the cart file This will synchronize the edited cart back to your project's .tic file The changes are saved to the file system, ready to be used in your game 2.4 Workflow Example Here's a typical workflow for editing a TIC-80 cart: Open the cart file: Click on TIC80/game.tic in the file tree Upload to Studio: Type add in the TIC80 terminal Edit in Studio: Use TIC80 Studio's editor to modify code, sprites, maps, sounds, etc. Save changes: Type get game.tic to save your changes back to the file Use in game: The updated cart file is now ready to be loaded by TIC80Node TipThis integrated workflow allows you to iterate quickly on TIC-80 games without leaving the Dora SSR development environment. You can edit, test, and refine your carts seamlessly. 2.5 Code Editing Support The Web IDE provides special support for TIC-80 code editing, making it easier to develop TIC-80 games with autocomplete, type checking, and other editor features. For Lua, Teal, and YueScript When a code file starts with -- tic80, the built-in compiler automatically enables TIC-80 API support, including autocomplete and type checking. No additional import statements are needed since TIC-80 APIs are global by default. Examples: LuaTealYueScript-- tic80TIC = function() cls() print("Hello World", 100, 64, 15)end-- tic80TIC = function() cls() print("Hello World", 100, 64, 15)end-- tic80TIC = -> cls! print "Hello World", 100, 64, 15 With the -- tic80 comment at the beginning, you'll get full autocomplete support for all TIC-80 APIs like print, cls, rect, circ, etc., as well as type checking for your code. For TypeScript When writing TypeScript code for TIC-80, import the TIC-80 module at the beginning of your file: import { print, _G } from 'tic80'; This enables TIC-80 development mode. You can then register callback functions using the _G object: import { print, cls, _G } from 'tic80';_G.TIC = () => { cls(); print("Hello World", 100, 64, 15);}; The _G object provides access to TIC-80's callback functions like TIC, BOOT, BDR, etc. This allows you to develop TIC-80 games using TypeScript with full type safety and editor support. Runtime Language SupportDora engine's TIC80 runtime only supports Lua and YueScript languages directly. Other languages like TypeScript and Teal need to be compiled to Lua code before execution in TIC-80. The code editing support mentioned above helps with development, but the actual execution always uses Lua or YueScript. 3. Creating a TIC80Node Instance 3.1 Creating from a Cart File The simplest way to create a TIC80Node is to load a complete cart file. This cart file contains all the code, graphics, and audio needed to run the game. LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")-- Create a TIC80Node from a cart filelocal tic80Game = TIC80Node("TIC80/game.tic")if tic80Game then -- Use the node print("TIC80 cart loaded successfully")else print("Failed to load TIC80 cart")endlocal TIC80Node <const> = require("TIC80Node")-- Create a TIC80Node from a cart filelocal tic80Game = TIC80Node("TIC80/game.tic")if not tic80Game is nil then -- Use the node print("TIC80 cart loaded successfully")else print("Failed to load TIC80 cart")endimport { TIC80Node } from "Dora";// Create a TIC80Node from a cart fileconst tic80Game = TIC80Node("TIC80/game.tic");if (tic80Game !== null) { // Use the node print("TIC80 cart loaded successfully");} else { print("Failed to load TIC80 cart");}_ENV = Dora-- Create a TIC80Node from a cart filetic80Game = TIC80Node "TIC80/game.tic"if tic80Game print "TIC80 cart loaded successfully"else print "Failed to load TIC80 cart" You can also load PNG-format cart files: LuaTealTypeScriptYueScript-- Load a PNG-format cart filelocal tic80Game = TIC80Node("TIC80/game.png")-- Load a PNG-format cart filelocal tic80Game = TIC80Node("TIC80/game.png")// Load a PNG-format cart fileconst tic80Game = TIC80Node("TIC80/game.png");-- Load a PNG-format cart filetic80Game = TIC80Node "TIC80/game.png" ImportantIf the cart file cannot be loaded or is invalid, TIC80Node() will return nil (or null in TypeScript). Always check if the node was created successfully before using it. 3.2 Creating from Resource Cart and Code File You can also create a TIC80Node by combining a resource cart file (containing graphics and audio) with a separate code file. This approach is useful for development workflows where you want to edit code separately from resources. LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")-- Create a TIC80Node from a resource cart and a code filelocal tic80Game = TIC80Node("TIC80/resources.tic", "TIC80/game.lua")if tic80Game then print("TIC80 cart loaded with external code")endlocal TIC80Node <const> = require("TIC80Node")-- Create a TIC80Node from a resource cart and a code filelocal tic80Game = TIC80Node("TIC80/resources.tic", "TIC80/game.lua")if not tic80Game is nil then print("TIC80 cart loaded with external code")endimport { TIC80Node } from "Dora";// Create a TIC80Node from a resource cart and a code fileconst tic80Game = TIC80Node("TIC80/resources.tic", "TIC80/game.lua");if (tic80Game !== null) { print("TIC80 cart loaded with external code");}_ENV = Dora-- Create a TIC80Node from a resource cart and a code filetic80Game = TIC80Node "TIC80/resources.tic", "TIC80/game.lua"if tic80Game print "TIC80 cart loaded with external code" The code file can be in .lua or .yue format. The resource cart file provides the graphics, audio, and other resources, while the code file contains the game logic. 4. Adding TIC80Node to the Scene Once you create a TIC80Node, you need to add it to the scene for it to be displayed and start running. Since TIC80Node inherits from Sprite, you can use all sprite properties and methods to control its display. LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")local Vec2 <const> = require("Vec2")local Director <const> = require("Director")-- Create a TIC80Nodelocal tic80Game = TIC80Node("TIC80/game.tic")if tic80Game then -- Set position tic80Game.position = Vec2(400, 300) -- Add to scene Director.entry:addChild(tic80Game)endlocal TIC80Node <const> = require("TIC80Node")local Vec2 <const> = require("Vec2")local Director <const> = require("Director")-- Create a TIC80Nodelocal tic80Game = TIC80Node("TIC80/game.tic")if not tic80Game is nil then -- Set position tic80Game.position = Vec2(400, 300) -- Add to scene Director.entry:addChild(tic80Game)endimport { TIC80Node, Vec2, Director } from "Dora";// Create a TIC80Nodeconst tic80Game = TIC80Node("TIC80/game.tic");if (tic80Game !== null) { // Set position tic80Game.position = Vec2(400, 300); // Add to scene Director.entry.addChild(tic80Game);}_ENV = Dora-- Create a TIC80Nodewith TIC80Node "TIC80/game.tic" -- Set position .position = Vec2 400, 300 -- Add to scene \addTo Director.entry You can also scale the TIC80Node to make it larger or smaller: LuaTealTypeScriptYueScript-- Scale the TIC80Node (240x136 native resolution)tic80Game.scaleX = 2.0 -- 2x widthtic80Game.scaleY = 2.0 -- 2x height-- Scale the TIC80Node (240x136 native resolution)tic80Game.scaleX = 2.0 -- 2x widthtic80Game.scaleY = 2.0 -- 2x height// Scale the TIC80Node (240x136 native resolution)tic80Game.scaleX = 2.0; // 2x widthtic80Game.scaleY = 2.0; // 2x height-- Scale the TIC80Node (240x136 native resolution)tic80Game.scaleX = 2.0 -- 2x widthtic80Game.scaleY = 2.0 -- 2x height Automatic ExecutionOnce a TIC80Node is added to the scene, the TIC-80 cart will start running automatically at 60 FPS. The cart will continue running as long as the node remains in the scene tree. 5. Helper Methods TIC80Node provides several static helper methods for working with TIC-80 cart files. 5.1 Extracting Code from a Cart You can extract the code from a cart file using the codeFromCart method: LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")-- Extract code from a cart filelocal code = TIC80Node:codeFromCart("TIC80/game.tic")print(code)local TIC80Node <const> = require("TIC80Node")-- Extract code from a cart filelocal code = TIC80Node:codeFromCart("TIC80/game.tic")print(code)import { TIC80Node } from "Dora";// Extract code from a cart fileconst code = TIC80Node.codeFromCart("TIC80/game.tic");print(code);_ENV = Dora-- Extract code from a cart filecode = TIC80Node\codeFromCart "TIC80/game.tic"print code 5.2 Merging Resources and Code into a .tic File The mergeTic method allows you to combine a resource cart file with a code file and save it as a .tic file: LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")-- Merge resource cart and code file into a .tic filelocal success = TIC80Node:mergeTic( "TIC80/output.tic", "TIC80/resources.tic", "TIC80/game.lua")if success then print("Cart file created successfully")else print("Failed to create cart file")endlocal TIC80Node <const> = require("TIC80Node")-- Merge resource cart and code file into a .tic filelocal success = TIC80Node:mergeTic( "TIC80/output.tic", "TIC80/resources.tic", "TIC80/game.lua")if success then print("Cart file created successfully")else print("Failed to create cart file")endimport { TIC80Node } from "Dora";// Merge resource cart and code file into a .tic fileconst success = TIC80Node.mergeTic( "TIC80/output.tic", "TIC80/resources.tic", "TIC80/game.lua");if (success) { print("Cart file created successfully");} else { print("Failed to create cart file");}_ENV = Dora-- Merge resource cart and code file into a .tic filesuccess = TIC80Node\mergeTic( "TIC80/output.tic", "TIC80/resources.tic", "TIC80/game.lua")if success print "Cart file created successfully"else print "Failed to create cart file" 5.3 Merging into a .png File The mergePng method allows you to create a PNG-format cart file with an optional cover image: LuaTealTypeScriptYueScriptlocal TIC80Node <const> = require("TIC80Node")-- Merge into a .png cart file with cover imagelocal success = TIC80Node:mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic", "TIC80/game.lua" -- Optional: if omitted, uses code from resource cart)-- Or without code file (uses code from resource cart)local success2 = TIC80Node:mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic")local TIC80Node <const> = require("TIC80Node")-- Merge into a .png cart file with cover imagelocal success = TIC80Node:mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic", "TIC80/game.lua" -- Optional: if omitted, uses code from resource cart)-- Or without code file (uses code from resource cart)local success2 = TIC80Node:mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic")import { TIC80Node } from "Dora";// Merge into a .png cart file with cover imageconst success = TIC80Node.mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic", "TIC80/game.lua" // Optional: if omitted, uses code from resource cart);// Or without code file (uses code from resource cart)const success2 = TIC80Node.mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic");_ENV = Dora-- Merge into a .png cart file with cover imagesuccess = TIC80Node\mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic", "TIC80/game.lua" -- Optional: if omitted, uses code from resource cart)-- Or without code file (uses code from resource cart)success2 = TIC80Node\mergePng( "TIC80/output.png", "TIC80/cover.png", "TIC80/resources.tic") 6. Notes and Best Practices 6.1 Obtaining Cart Files TIC-80 cart files can be obtained in several ways: Create your own: Use the TIC-80 editor (or Web IDE integration) to create games Download from community: Many TIC-80 games are available from the TIC-80 community Export from TIC-80: If you're developing in the standalone TIC-80 editor, export your cart as a .tic or .png file 6.2 Input Handling TIC80Node automatically handles input mapping: Keyboard: Standard keyboard input is automatically mapped to TIC-80 controls Game Controllers: Controller input is mapped to TIC-80's gamepad API Touch Input: Touch events are mapped to TIC-80's mouse/touch API 6.3 Performance Considerations Fixed Frame Rate: TIC80Node runs at a fixed 60 FPS, matching TIC-80's specification. This ensures consistent gameplay timing. Resolution: The native resolution is 240x136 pixels. You can scale the node, but the internal rendering remains at this resolution. Resource Usage: Each TIC80Node instance runs a complete TIC-80 virtual machine, so having many instances may impact performance. 6.4 Web IDE Integration Workflow Using the Web IDE integration provides several advantages: Seamless editing: Edit carts directly within your development environment Quick iteration: Use add and get commands to quickly test changes Integrated workflow: No need to switch between different tools Version control friendly: Cart files are binary files, but you can maintain the external TIC80 code files that work with version control 7. Conclusion In this tutorial, you learned how to: Understand TIC-80 cart file formats and TIC80Node features Use the Web IDE integration to edit TIC-80 carts with add and get commands Create TIC80Node instances from cart files or by combining resource carts with code files Add TIC80Node to scenes and control its display properties Use helper methods to extract code and merge resources into cart files Follow best practices for working with TIC-80 carts in Dora SSR TIC80Node provides a playful way to integrate retro-style games and programs into your Dora SSR projects. The Web IDE integration makes it easy to develop and iterate on TIC-80 carts, while the node system allows you to seamlessly integrate them into your game scenes. For more information about TIC80Node, refer to the TIC80Node API documentation.